/**
 * Copyright 2006 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ocean.server;

import java.io.IOException;
import java.io.Reader;
import java.util.EnumSet;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Payload;
import org.apache.ocean.analysis.SolrAnalyzer;


/**
 *
 */
public final class SchemaField {
  public String name;
  public FieldType fieldType;
  public static enum Attribute { INDEXED, TOKENIZED, STORED, BINARY, COMPRESSED, 
  	OMITNORMS, STORETERMVECTOR, STORETERMPOSITIONS, STORETERMOFFSETS, 
  	MULTIVALUED, FIELDCACHEPAYLOAD, STOREASPAYLOAD}
  private EnumSet<Attribute> attributes = EnumSet.noneOf(Attribute.class);// = new EnumSet<Info>();
  
  // TODO: change these booleans to a hashset
  /**
  public SchemaField(String name, SchemaField schemaField) {
    this.name = name;
    this.fieldType = schemaField.fieldType;
    this.indexed = schemaField.indexed;
    this.tokenized = schemaField.tokenized;
    this.stored = schemaField.stored;
    this.binary = schemaField.binary;
    this.compressed = schemaField.compressed;
    this.omitNorms = schemaField.omitNorms;
    this.storeTermVector = schemaField.storeTermVector;
    this.storeTermPositions = schemaField.storeTermPositions;
    this.storeTermOffsets = schemaField.storeTermOffsets;
    this.multiValued = schemaField.multiValued;
  }
  **/
  /** Create a new SchemaField with the given name and type,
   *  using all the default properties from the type.
   */
  public SchemaField(String name, FieldType fieldType) {
    this.name = name;
    this.fieldType = fieldType;
  }
  
  public void addAttribute(Attribute attribute) {
  	attributes.add(attribute);
  }
  
  public boolean has(Attribute attribute) {
  	return attributes.contains(attribute);
  }
  
  public byte[] toPayload(String string) {
  	return null;
  }
  
  /**
   * Default analyzer for types that only produce 1 verbatim token...
   * A maximum size of chars to be read must be specified
   */
  public class DefaultAnalyzer extends SolrAnalyzer {
    final int maxChars;

    DefaultAnalyzer(int maxChars) {
      this.maxChars = maxChars;
    }

    public TokenStream tokenStream(String fieldName, Reader reader) {
      return new Tokenizer(reader) {
        char[] chars = new char[maxChars];
        public Token next() throws IOException {
          int n = input.read(chars, 0, maxChars);
          if (n <= 0) return null;
          String string = new String(chars, 0, n);
          String internalString = fieldType.toInternal(string); 
          Token token = new Token(internalString, 0, n);
          if (attributes.contains(Attribute.STOREASPAYLOAD)) {
          	byte[] payload = toPayload(string);
          	if (payload != null) {
          	  token.setPayload(new Payload(payload));
          	}
          }
          return token;
        };
      };
    }
  }
  
  public Analyzer getAnalyzer() {
  	
  	return null;
  }
  
  public SchemaField() {
  }
  
  public String toString() {
    return ReflectionToStringBuilder.toString(this);
  }
  
  public String getName() { return name; }
  public FieldType getFieldType() { return fieldType; }

  public Fieldable createField(String val, float boost) {
    return fieldType.createField(this, val, boost);
  }
}
